<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>window.performance User Timing measure() method is throwing the proper exceptions</title>
        <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
        <link rel="help" href="http://www.w3.org/TR/user-timing/#dom-performance-measure"/>
        <script src="/resources/testharness.js"></script>
        <script src="/resources/testharnessreport.js"></script>
        <script src="resources/webperftestharness.js"></script>

    <script type="text/javascript">
        // navigation timing attributes
        var timingAttributes = [
            'connectEnd',
            'connectStart',
            'domComplete',
            'domContentLoadedEventEnd',
            'domContentLoadedEventStart',
            'domInteractive',
            'domLoading',
            'domainLookupEnd',
            'domainLookupStart',
            'fetchStart',
            'loadEventEnd',
            'loadEventStart',
            'navigationStart',
            'redirectEnd',
            'redirectStart',
            'requestStart',
            'responseEnd',
            'responseStart',
            'unloadEventEnd',
            'unloadEventStart'
        ];

        // test data
        var zeroedNavTimingAtt = undefined;

        setup({explicit_done: true});

        test_namespace();

        function onload_test()
        {
            // test for existance of User Timing and Performance Timeline interface
            if (window.performance.mark == undefined ||
                window.performance.clearMarks == undefined ||
                window.performance.measure == undefined ||
                window.performance.clearMeasures == undefined ||
                window.performance.getEntriesByName == undefined ||
                window.performance.getEntriesByType == undefined ||
                window.performance.getEntries == undefined)
            {
                test_true(false,
                          "The User Timing and Performance Timeline interfaces, which are required for this test, " +
                          "are defined.");

                done();
            }
            else
            {
                test_measure_exceptions();
            }
        }

        function test_measure_exceptions()
        {
            // test scenarios for the SYNTAX_ERR exception
            try
            {
                // create the measure
                window.performance.measure("measure", "mark");

                test_true(false,
                          "window.performance.measure(\"measure\", \"mark\"), where \"mark\" is a non-existent mark, " +
                          "threw an exception.");
            }
            catch(e)
            {
                test_true(true,
                          "window.performance.measure(\"measure\", \"mark\"), where \"mark\" is a non-existent mark, " +
                          " threw an exception.");

                test_equals(e.code,
                            e.SYNTAX_ERR,
                            "window.performance.measure(\"measure\", \"mark\"), where \"mark\" is a non-existent " +
                            "mark, threw a SYNTAX_ERR exception.");
            }

            try
            {
                // create the measure
                window.performance.measure("measure", "mark", "responseEnd");

                test_true(false,
                          "window.performance.measure(\"measure\", \"mark\", \"responseEnd\"), where \"mark\" is a " +
                          "non-existent mark, threw an exception.");
            }
            catch(e)
            {
                test_true(true,
                          "window.performance.measure(\"measure\", \"mark\", \"responseEnd\"), where \"mark\" is a " +
                          "non-existent mark, threw an exception.");

                test_equals(e.code,
                            e.SYNTAX_ERR,
                            "window.performance.measure(\"measure\", \"mark\", \"responseEnd\"), where \"mark\" is a " +
                            "non-existent mark, threw a SYNTAX_ERR exception.");
            }

            try
            {
                // create the measure
                window.performance.measure("measure", "navigationStart", "mark");

                test_true(false,
                          "window.performance.measure(\"measure\", \"navigationStart\", \"mark\"), where \"mark\" is " +
                          "a non-existent mark, threw an exception.");
            }
            catch(e)
            {
                test_true(true,
                          "window.performance.measure(\"measure\", \"navigationStart\", \"mark\"), where \"mark\" is " +
                          "a non-existent mark, threw an exception.");

                test_equals(e.code,
                            e.SYNTAX_ERR,
                            "window.performance.measure(\"measure\", \"navigationStart\", \"mark\"), where \"mark\" " +
                            "is a non-existent mark, threw a SYNTAX_ERR exception.");
            }

            try
            {
                // create the measure
                window.performance.measure("measure", "mark", "mark");

                test_true(false,
                          "window.performance.measure(\"measure\", \"mark\", \"mark\"), where \"mark\" is a " +
                          "non-existent mark, threw an exception.");
            }
            catch(e)
            {
                test_true(true,
                          "window.performance.measure(\"measure\", \"mark\", \"mark\"), where \"mark\" is a " +
                          "non-existent mark, threw an exception.");

                test_equals(e.code,
                            e.SYNTAX_ERR,
                            "window.performance.measure(\"measure\", \"mark\", \"mark\"), where \"mark\" is a " +
                            "non-existent mark, threw a SYNTAX_ERR exception.");
            }


            // for testing the INVALID_ACCESS_ERR exception, find a navigation timing attribute with a value of zero
            for (var i in timingAttributes)
            {
                if (window.performance.timing[timingAttributes[i]] == 0)
                {
                    zeroedNavTimingAtt = timingAttributes[i];
                }
            }

            if (zeroedNavTimingAtt == undefined)
            {
                test_true(false,
                          "A navigation timing attribute with a value of 0 was not found to test for the " +
                          "INVALID_ACCESS_ERR exception thrown by window.performance.measure().");
            }
            else
            {
                try
                {
                    // create the measure
                    window.performance.measure("measure", zeroedNavTimingAtt);

                    test_true(false,
                              "window.performance.measure(\"measure\", \"" + zeroedNavTimingAtt + "\"), where \"" +
                              zeroedNavTimingAtt + "\" is a navigation timing attribute with a value of 0, threw an " +
                              "exception.");
                }
                catch(e)
                {
                    test_true(true,
                              "window.performance.measure(\"measure\", \"" + zeroedNavTimingAtt + "\"), where \"" +
                              zeroedNavTimingAtt + "\" is a navigation timing attribute with a value of 0, threw an " +
                              "exception.");

                    test_equals(e.code,
                                e.INVALID_ACCESS_ERR,
                                "window.performance.measure(\"measure\", \"" + zeroedNavTimingAtt + "\"), where \"" +
                                zeroedNavTimingAtt + "\" is a navigation timing attribute with a value of 0, threw " +
                                "an INVALID_ACCESS_ERR exception.");
                }

                try
                {
                    // create the measure
                    window.performance.measure("measure", zeroedNavTimingAtt, "responseEnd");

                    test_true(false,
                              "window.performance.measure(\"measure\", \"" + zeroedNavTimingAtt + "\", " +
                              "\"responseEnd\"), where \"" + zeroedNavTimingAtt + "\" is a navigation timing " +
                              "attribute with a value of 0, threw an exception.");
                }
                catch(e)
                {
                    test_true(true,
                              "window.performance.measure(\"measure\", \"" + zeroedNavTimingAtt + "\", " +
                              "\"responseEnd\"), where \"" + zeroedNavTimingAtt + "\" is a navigation timing " +
                              "attribute with a value of 0, threw an exception.");

                    test_equals(e.code,
                                e.INVALID_ACCESS_ERR,
                                "window.performance.measure(\"measure\", \"" + zeroedNavTimingAtt + "\", " +
                                "\"responseEnd\"), where \"" + zeroedNavTimingAtt + "\" is a navigation timing " +
                                "attribute with a value of 0, threw an INVALID_ACCESS_ERR exception.");
                }

                try
                {
                    // create the measure
                    window.performance.measure("measure", "navigationStart", zeroedNavTimingAtt);

                    test_true(false,
                              "window.performance.measure(\"measure\", \"navigationStart\", \"" + zeroedNavTimingAtt +
                              "\"), where \"" + zeroedNavTimingAtt + "\" is a navigation timing attribute with a " +
                              "value of 0, threw an exception.");
                }
                catch(e)
                {
                    test_true(true,
                              "window.performance.measure(\"measure\", \"navigationStart\", \"" + zeroedNavTimingAtt +
                              "\"), where \"" + zeroedNavTimingAtt + "\" is a navigation timing attribute with a " +
                              "value of 0, threw an exception.");

                    test_equals(e.code,
                                e.INVALID_ACCESS_ERR,
                                "window.performance.measure(\"measure\", \"navigationStart\", \"" + zeroedNavTimingAtt +
                                "\"), where \"" + zeroedNavTimingAtt + "\" is a navigation timing attribute with a " +
                                "value of 0, threw an INVALID_ACCESS_ERR exception.");
                }

                try
                {
                    // create the measure
                    window.performance.measure("measure", zeroedNavTimingAtt, zeroedNavTimingAtt);

                    test_true(false,
                              "window.performance.measure(\"measure\", \"" + zeroedNavTimingAtt + "\", \"" +
                              zeroedNavTimingAtt + "\"), where \"" + zeroedNavTimingAtt + "\" is a navigation timing " +
                              "attribute with a value of 0, threw an exception.");
                }
                catch(e)
                {
                    test_true(true,
                              "window.performance.measure(\"measure\", \"" + zeroedNavTimingAtt + "\", \"" +
                              zeroedNavTimingAtt + "\"), where \"" + zeroedNavTimingAtt + "\" is a navigation timing " +
                              "attribute with a value of 0, threw an exception.");

                    test_equals(e.code,
                                e.INVALID_ACCESS_ERR,
                                "window.performance.measure(\"measure\", \"" + zeroedNavTimingAtt + "\", \"" +
                                zeroedNavTimingAtt + "\"), where \"" + zeroedNavTimingAtt + "\" is a navigation " +
                                "timing attribute with a value of 0, threw an INVALID_ACCESS_ERR exception.");
                }
            }

            done();
        }
    </script>
    </head>
    <body onload="onload_test();">
        <h1>Description</h1>
        <p>This test validates that the performance.measure() method throws a SYNTAX_ERR exception whenever a
           non-existent mark is provided as the startMark or endMark, and the method also throws a INVALID_ACCESS_ERR
           whenever a navigation timing attribute with a value of zero is provided as the startMark or endMark.
        </p>

        <div id="log"></div>
    </body>
</html>
